package Application;

import java.util.ArrayList;
import java.util.List;

import VectorApproach.Time;
import VectorApproach.TrajVector;
import XmlLoader.FGObjectStructure;
import XmlLoader.FGObjectTrajectoryStructure;
import XmlLoader.Position;


/**
 * 
 * Class Douglas.java
 * 
 * Description
 * 
 * Company mapbar
 * 
 * author Chenll E-mail: Chenll@mapbar.com
 * 
 * Version 1.0
 * 
 * Date 2012-6-28 下午02:53:58
 */
public class TrajSplit {

	/**
	 * 存储采样点数据的链表
	 */
	public List<Position> Positions = new ArrayList<Position>();
	
	protected FGObjectTrajectoryStructure curTraj = null;

	/**
	 * 控制数据压缩精度的极差
	 */
	private double D = -1;
	
	public TrajSplit(double D) {
		this.D = D;
	}
	/**
	 * 读取采样点
	 */
	public void readPosition(FGObjectTrajectoryStructure traj) {
		this.curTraj = traj;
		FGObjectStructure fs = null;
		this.Positions.clear();
		for (int i = 0; i < traj.GET002_nNumberOfPoint(); i++) {
			fs = traj.GET003_elementIn_list_fGObject(i);
			Position p = new Position(fs.GET001_centerReal().x, fs.GET001_centerReal().y, i);
			this.Positions.add(p);
		}
	}
	
	public void setPositionByHand() {
		Positions.add(new Position(1,4,0));
		Positions.add(new Position(1,20,1));
		Positions.add(new Position(10,2,2));
		Positions.add(new Position(18,5,3));
	}

	/**
	 * 对矢量曲线进行压缩
	 * 
	 * @param from
	 *            曲线的起始点
	 * @param to
	 *            曲线的终止点
	 */
	public void compress(Position from, Position to) {

		/**
		 * 压缩算法的开关量
		 */
		boolean switchvalue = false;

		/**
		 * 由起始点和终止点构成的直线方程一般式的系数
		 */
		//System.out.println(from.getY());
		//System.out.println(to.getY());
		double A = (from.getY() - to.getY())
				/ Math.sqrt(Math.pow((from.getY() - to.getY()), 2)
						+ Math.pow((from.getX() - to.getX()), 2));

		/**
		 * 由起始点和终止点构成的直线方程一般式的系数
		 */
		double B = (to.getX() - from.getX())
				/ Math.sqrt(Math.pow((from.getY() - to.getY()), 2)
						+ Math.pow((from.getX() - to.getX()), 2));

		/**
		 * 由起始点和终止点构成的直线方程一般式的系数
		 */
		double C = (from.getX() * to.getY() - to.getX() * from.getY())
				/ Math.sqrt(Math.pow((from.getY() - to.getY()), 2)
						+ Math.pow((from.getX() - to.getX()), 2));

		double d = 0;
		double dmax = 0;
		int m = Positions.indexOf(from);
		int n = Positions.indexOf(to);
		if (n == m + 1)
			return;
		Position middle = null;
		List<Double> distance = new ArrayList<Double>();
		for (int i = m + 1; i < n; i++) {
			d = Math.abs(A * (Positions.get(i).getX()) + B
					* (Positions.get(i).getY()) + C)
					/ Math.sqrt(Math.pow(A, 2) + Math.pow(B, 2));
			distance.add(d);
		}
		dmax = distance.get(0);
		for (int j = 1; j < distance.size(); j++) {
			if (distance.get(j) > dmax)
				dmax = distance.get(j);
		}
		if (dmax > D)
			switchvalue = true;
		else
			switchvalue = false;
		if (!switchvalue) {
			// 删除Positions(m,n)内的坐标
			for (int i = m + 1; i < n; i++) {
				Positions.get(i).setIndex(-1);
			}

		} else {
			for (int i = m + 1; i < n; i++) {
				if ((Math.abs(A * (Positions.get(i).getX()) + B
						* (Positions.get(i).getY()) + C)
						/ Math.sqrt(Math.pow(A, 2) + Math.pow(B, 2)) == dmax))
					middle = Positions.get(i);
			}
			compress(from, middle);
			compress(middle, to);
		}
	}
	
	public ArrayList<TrajVector> transfromVector(int maxLength) {
		ArrayList<TrajVector> list = new ArrayList<TrajVector>();
		Position p1 = null, p2 = null;
		int t1 = -1, t2 = -1;
		int index = 0, segIndex = 0;
		while(index < this.Positions.size()) {
			Position getP = this.Positions.get(index);
			if(getP.getIndex() > -1) {
				if(p1 == null) {  //assign first point
					p1 = getP;
					//t1 = this.curTraj.GET003_elementIn_list_fGObject(index).GET002_tOrigin();
				}
				else {  //assign last point and store vector and id
					p2 = getP;
					//t2 = this.curTraj.GET003_elementIn_list_fGObject(index).GET002_tOrigin();
					TrajVector traj = new TrajVector(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y, 
							this.curTraj.GET001_nobjNewNumIndex(), segIndex, 
							new Time(t1, t2));
					ArrayList<TrajVector> listSubTraj = traj.ACT004_split(maxLength, segIndex);
					for(int i=0; i<listSubTraj.size(); i++) {
						list.add(listSubTraj.get(i));
					}
					segIndex = segIndex + listSubTraj.size();
					p1 = p2;
					p2 = null;
				}
			}
			index = index + 1;
		}
		return list;
	}

	public static void main(String[] args) {
		TrajSplit d = new TrajSplit(1);
		d.setPositionByHand();
		d.compress(d.Positions.get(0), d.Positions.get(d.Positions.size() - 1));
		ArrayList<TrajVector> listV = d.transfromVector(5);
		
		int index = 0;
		while(index < listV.size()) {
			System.out.println(listV.get(index).GET002_trajSegID() + ":" + listV.get(index).startPos.x + " " +  listV.get(index).startPos.y);
			index = index + 1;
		}
	}
}
